﻿Imports Equipment.Core
Imports Equipment.DataAccess
Imports Equipment.Business
Imports Equipment.Model
Imports System.Globalization

Namespace Equipment
    <RequiresAuthentication()> _
    Public Class WorkOrderController
        Inherits System.Web.Mvc.Controller

        Private SUCCESS_VALUE_SAVED_MESSAGE As String = "Values have been saved successfully."
        Private ERROR_MESSAGE As String = "Error."

#Region "Manage WorkOrder"

        <RequiresPageAcces(Page:=PageType.ManageWorkOrder)> _
        Function Index() As ActionResult

            Dim userTimeNow As DateTime = DateTime.UtcNow.Date
            Dim dateFrom As DateTime = userTimeNow.AddDays(-userTimeNow.Day + 1)
            Dim dateTo As DateTime = userTimeNow.AddDays(1).AddSeconds(-1)

            Dim groups As IEnumerable = GroupManager.GetAllFor(Application.CurrentUserInfo)
            Dim workOrderList As IEnumerable(Of WorkOrder) = WorkOrderManager.GetAllFor(Application.CurrentUserInfo, _
                                                                                       TimeZoneManager.ConvertToCentralTimeFor(DateTime.Parse(dateFrom.ToString("dd-MMM-yyyy"))), _
                                                                                       TimeZoneManager.ConvertToCentralTimeFor(DateTime.Parse(dateTo.ToString("dd-MMM-yyyy")).AddDays(1).AddSeconds(-1)))
            Dim sites As IEnumerable(Of SiteDepartment) = SiteDepartmentManager.GetAllSitesFor(Application.CurrentUserInfo)
            ViewData("Site") = New SelectList(sites, "ID", "Description")

            Dim departments As IEnumerable(Of SiteDepartment) = New List(Of SiteDepartment)
            ViewData("Department") = New SelectList(departments, "ID", "Description")

            Dim assetList As IEnumerable(Of Asset) = AssetManager.GetAllFor(Application.CurrentUserInfo)

            ViewData("AssetType") = New SelectList(AssetType.RetrieveAll(), "ID", "Description")
            ViewData("Group") = New SelectList(groups, "ID", "Description")
            ViewData("Status") = New SelectList(WorkOrderStatus.RetrieveFilterAll(), "ID", "Description")
            ViewData("WorkOrderList") = workOrderList
            ViewData("EntityType") = EntityType.WorkOrder
            ViewData("Assets") = assetList
            ViewData("DateFrom") = dateFrom.ToString("dd-MMM-yyyy")
            ViewData("DateTo") = dateTo.ToString("dd-MMM-yyyy")
            Session("BackURL") = "Index"
            Return View()
        End Function

#End Region

#Region "Process"

        <RequiresPageAcces(Page:=PageType.ProcessWorkOrder)> _
        Function Process(ByVal id As Integer) As ActionResult
            If id = 0 Then
                id = WorkOrder.GetNextID() - 1
            End If
            Dim currWorkOrder = WorkOrder.GetByPrimaryKey(id)
            InitProcessControls(currWorkOrder)
            Return View()
        End Function

        <HttpPost()> _
        <RequiresPageAcces(Page:=PageType.ProcessWorkOrder)> _
        Function Process(ByVal id As Integer, ByVal collection As FormCollection) As ActionResult
            Dim currWorkOrder = WorkOrder.GetByPrimaryKey(id)
            Dim changeDetails As New List(Of String)
            Try
                For Each measure In currWorkOrder.Measures
                    Dim type As String = collection(String.Format("measureType_{0}", measure.ID))
                    Dim val As String = collection(String.Format("measure_{0}", measure.ID))
                    Dim comments As String = collection(String.Format("measureComment_{0}", measure.ID))
                    If Not String.IsNullOrEmpty(val) Then
                        If type = MeasureType.Checkbox Then
                            Dim lookup As String() = measure.LookupValue.Split(";")
                            If val.Split(",")(0) = "true" Then
                                val = lookup(0)
                            Else
                                val = lookup(1)
                            End If
                        End If

                        If (measure.CalibratedValue <> val) Then
                            changeDetails.Add(String.Format("Changed '{0}' measure value to: {1}", measure.MeasureDescription, val))
                        End If
                        If (measure.MeasureComments <> comments) Then
                            changeDetails.Add(String.Format("Changed '{0}' measure comments", measure.MeasureDescription))
                        End If

                        measure.SetValue(val)
                        measure.SetComments(comments)
                    End If
                Next

                currWorkOrder.Status = WorkOrderStatusType.AwaitingPost
                currWorkOrder.DateOpened = DateTime.Now.ToUniversalTime()

                If Not ModelState.IsValid Then
                    InitWorkOrderControls(currWorkOrder)
                    Return View()
                End If

                If Not currWorkOrder.PerformedDate.HasValue Then
                    currWorkOrder.PerformedBy = Application.CurrentUserInfo.UserID
                    currWorkOrder.PerformedDate = DateTime.Now.ToUniversalTime()
                End If


                currWorkOrder.Save()
                ModificationHistory.Insert(EntityType.WorkOrder, String.Format("Work Order #{0}", currWorkOrder.ID), _
                                            ModificationAction.Modified, Application.CurrentUserInfo.UserID, changeDetails, _
                                            currWorkOrder.ID, currWorkOrder.Asset.SiteDepartment.ParentID)
                NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.WorkOrder_Calibrate, currWorkOrder.ID, currWorkOrder)
                NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.WorkOrder_StatusChange, currWorkOrder.ID, currWorkOrder)
                ViewData("Success_Mess") = SUCCESS_VALUE_SAVED_MESSAGE
                
            Catch

            End Try

            currWorkOrder = WorkOrder.GetByPrimaryKey(id)
            InitProcessControls(currWorkOrder)
            Return View()
        End Function

        Private Sub InitProcessControls(ByRef currWorkOrder As WorkOrder)
            ViewData("CurrWorkOrder") = currWorkOrder
            ViewData("RequirementType") = RequirementTypeLookup.GetDescriptionByType(currWorkOrder.RequirementType)
            ViewData("ReviewType") = RequirementReviewLookup.GetDescriptionByType(currWorkOrder.ReviewType)
            ViewData("Groups") = New SelectList(currWorkOrder.Groups, "ID", "Description")
            ViewData("ReviewGroups") = New SelectList(currWorkOrder.ReviewGroups, "ID", "Description")
        End Sub
#End Region

        Function Details(ByVal id As Integer) As ActionResult
            Return View()
        End Function

#Region "Review Work Orders"
        <RequiresPageAcces(Page:=PageType.ReviewWorkOrder)> _
        Function Review() As ActionResult
            InitReviewControls()
            Session("BackURL") = "Review"
            Return View()
        End Function

        <HttpPost()> _
        <RequiresPageAcces(Page:=PageType.ReviewWorkOrder)> _
        Function Review(ByVal collection As FormCollection) As ActionResult

            Dim awaitingReviewOrders = WorkOrder.RetrieveAllByStatuses(WorkOrderStatusType.ReadyForReview, WorkOrderStatusType.ReadyForReviewWithExceptions)
            Try
                For Each wo In awaitingReviewOrders
                    Dim formIsWOChecked As Boolean = Boolean.Parse(collection(String.Format("cbxWorkOrder_{0}", wo.ID)).Split(",")(0))
                    If formIsWOChecked Then
                        wo.Approve(WorkOrderStatusType.Complete, Application.CurrentUserInfo.UserID)
                        NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.WorkOrder_StatusChange, wo.ID.ToString(), wo)
                    End If
                Next
            Catch ex As Exception

            End Try

            InitReviewControls()
            Return View()
        End Function

        Private Sub InitReviewControls()
            Dim dateFrom As DateTime = DateTime.UtcNow.Date.AddDays(-DateTime.UtcNow.Date.Day + 1)
            Dim dateTo As DateTime = DateTime.UtcNow.Date.AddDays(1).AddSeconds(-1)

            Dim groups As IQueryable = GroupManager.GetAllFor(Application.CurrentUserInfo)
            Dim workOrderList As IEnumerable(Of WorkOrder) = WorkOrderManager.GetAllForReview(Application.CurrentUserInfo, _
                                                                                              TimeZoneManager.ConvertToUserTimeFor(dateFrom), TimeZoneManager.ConvertToUserTimeFor(dateTo))
            Dim locations As IEnumerable(Of SiteDepartment) = SiteDepartmentManager.GetAllFor(Application.CurrentUserInfo)


            ViewData("AssetType") = New SelectList(AssetType.RetrieveAll(), "ID", "Description")
            ViewData("Department") = New SelectList(locations, "ID", "Description")
            ViewData("Group") = New SelectList(groups, "ID", "Description")
            ViewData("Status") = New SelectList(WorkOrderStatus.RetrieveAllReview(), "ID", "Description")
            ViewData("WorkOrderList") = workOrderList
            ViewData("EntityType") = EntityType.WorkOrder
            ViewData("DateFrom") = dateFrom.ToString("dd-MMM-yyyy")
            ViewData("DateTo") = dateTo.ToString("dd-MMM-yyyy")
        End Sub
#End Region

#Region "Posting Work Orders"
        <RequiresPageAcces(Page:=PageType.PostWorkOrder)> _
        Function Posting() As ActionResult
            InitPostingControls()
            Session("BackURL") = "Posting"
            Return View()
        End Function

        <HttpPost()> _
        <RequiresPageAcces(Page:=PageType.PostWorkOrder)> _
        Function Posting(ByVal collection As FormCollection) As ActionResult

            Dim awaitingPostOrders = WorkOrderManager.GetAllByStatusFor(Application.CurrentUserInfo, WorkOrderStatusType.AwaitingPost)
            Try
                For Each wo In awaitingPostOrders
                    Dim formIsWOChecked As Boolean = Boolean.Parse(collection(String.Format("cbxWorkOrder_{0}", wo.ID)).Split(",")(0))
                    If formIsWOChecked Then
                        PostWorkOrder(wo)
                    End If
                Next
            Catch ex As Exception

            End Try

            InitPostingControls()
            Return View()
        End Function

        Private Sub PostWorkOrder(ByVal wo As WorkOrder)
            Dim woStatus As WorkOrderStatusType = WorkOrderStatusType.Complete
            Dim hasException As Boolean = False
            Dim provider As New CultureInfo("en-US")


            For Each m In wo.Measures
                If (m.MeasureType = MeasureType.Radiobutton Or m.MeasureType = MeasureType.Checkbox Or _
                     m.MeasureType = MeasureType.Dropdown) AndAlso m.OptimalLookupValue <> m.CalibratedValue Then
                    hasException = True
                ElseIf m.MeasureType = MeasureType.Integer AndAlso (m.IntegerMin > Integer.Parse(m.CalibratedValue) AndAlso _
                    Integer.Parse(m.CalibratedValue) > m.IntegerMax) Then
                    hasException = True
                ElseIf m.MeasureType = MeasureType.Decimal AndAlso (m.DecimalMin > Decimal.Parse(m.CalibratedValue, provider) Or _
                    Decimal.Parse(m.CalibratedValue, provider) > m.DecimalMax) Then
                    hasException = True
                End If
            Next
            If (wo.ReviewType = RequirementReviewType.Required Or wo.ReviewType = RequirementReviewType.RequiredOnlyForException) Then
                If hasException Then
                    woStatus = WorkOrderStatusType.ReadyForReviewWithExceptions
                Else
                    woStatus = WorkOrderStatusType.ReadyForReview
                End If
            End If
            wo.ChangeStatusTo(woStatus)
            wo.MarkException(hasException)
            NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.WorkOrder_StatusChange, wo.ID, wo)
        End Sub

        Private Sub InitPostingControls()

            Dim dateFrom As DateTime = DateTime.UtcNow.Date.AddDays(-DateTime.UtcNow.Date.Day + 1)
            Dim dateTo As DateTime = DateTime.UtcNow.Date.AddDays(1).AddSeconds(-1)

            Dim workOrderList As IEnumerable(Of WorkOrder) = WorkOrderManager.GetAllByStatusFor(Application.CurrentUserInfo, _
                                                                                                TimeZoneManager.ConvertToUserTimeFor(dateFrom), _
                                                                                                TimeZoneManager.ConvertToUserTimeFor(dateTo), _
                                                                                                WorkOrderStatusType.AwaitingPost)
            Dim locations As IEnumerable(Of SiteDepartment) = SiteDepartmentManager.GetAllFor(Application.CurrentUserInfo)

            ViewData("AssetType") = New SelectList(AssetType.RetrieveAll(), "ID", "Description")
            ViewData("Department") = New SelectList(locations, "ID", "Description")
            ViewData("WorkOrderList") = workOrderList
            ViewData("DateFrom") = dateFrom.ToString("dd-MMM-yyyy")
            ViewData("DateTo") = dateTo.ToString("dd-MMM-yyyy")
        End Sub
#End Region

#Region "Create"
        <RequiresPageAcces(Page:=PageType.CreateWorkOrder)> _
        Function Create(ByVal id As Integer?) As ActionResult
            Dim sites As IEnumerable(Of SiteDepartment) = SiteDepartmentManager.GetAllSiteWithAssetFor(Application.CurrentUserInfo)
            Dim baseOnAsset As Asset
            If Not id.HasValue Then
                id = 0
            End If
            If id > 0 Then
                baseOnAsset = Asset.GetByPrimaryKey(id)
            Else
                baseOnAsset = New Asset()
                baseOnAsset.AssetID = 0
                baseOnAsset.AssetType = New AssetType With {.ID = 0, .Description = String.Empty}
                baseOnAsset.SiteDepartment = New SiteDepartment With {.ID = 0, .Description = String.Empty}
            End If

            ViewData("FilterSite") = New SelectList(sites, "ID", "Description")
            ViewData("BasedOnAsset") = baseOnAsset
            Return View()
        End Function

        <HttpPost()> _
        <RequiresPageAcces(Page:=PageType.CreateWorkOrder)> _
        Function Create(ByVal collection As FormCollection) As ActionResult

            Try
                Dim creationTrigger As NotificationTrigger = NotificationTrigger.WorkOrder_Create
                Dim formAssetID As Integer = Integer.Parse(collection("hfAssetID"))
                Dim formRequirementType As RequirementType = [Enum].Parse(GetType(RequirementType), collection("RequirementType"))
                Dim formRequirementID As String = collection("RequirementID")
                Dim formDueTime As String = collection("txtDate")
                Dim reviewType As RequirementReviewType = [Enum].Parse(GetType(RequirementReviewType), collection("ReviewType"))
                Dim formDesc As String = collection("txtDetails")
                Dim Details As New List(Of String)

                Dim dueDate As DateTime = DateTime.Now

                DateTime.TryParse(formDueTime, dueDate)

                Dim newWorkOrder As New WorkOrder()


                If Not String.IsNullOrEmpty(formRequirementID) Then

                    Dim woAsset As Asset = Asset.GetByPrimaryKey(formAssetID)
                    Dim reqID As Integer = Integer.Parse(formRequirementID)
                    Dim groups = GroupManager.GetAllByDepartmentFor(woAsset.SiteDepartmentID, Application.CurrentUserInfo)

                    newWorkOrder.AssetID = formAssetID
                    newWorkOrder.RequirementType = formRequirementType
                    Details.Add(String.Format("Selected Work Order Type: {0}", formRequirementType))
                    If reqID > 0 Then
                        Details.Add(String.Format("Select Requirement: {0}", formRequirementID))
                    End If
                    newWorkOrder.DateDue = TimeZoneManager.ConvertToCentralTimeFor(dueDate, Application.CurrentUserInfo)
                    newWorkOrder.DateCreated = DateTime.Now.ToUniversalTime()
                    newWorkOrder.DateOpened = DateTime.Now.ToUniversalTime()
                    newWorkOrder.ReviewType = reviewType
                    Details.Add(String.Format("Selected Review Type: {0}", reviewType))
                    newWorkOrder.Description = formDesc
                    newWorkOrder.Status = WorkOrderStatusType.ManuallyCreated

                    For Each groupItem In groups
                        Dim stringSelectedGroup As String = collection(String.Format("cbxGroup_{0}", groupItem.ID))
                        Dim stringSelectedReviewGroup As String = collection(String.Format("cbxReviewGroup_{0}", groupItem.ID))
                        Dim selectedGroup As Boolean = False
                        Dim selectedReviewGroup As Boolean = False
                        If Not String.IsNullOrEmpty(stringSelectedGroup) Then
                            selectedGroup = Boolean.Parse(stringSelectedGroup.Split(",")(0))
                        End If

                        If Not String.IsNullOrEmpty(stringSelectedGroup) Then
                            selectedReviewGroup = Boolean.Parse(stringSelectedReviewGroup.Split(",")(0))
                        End If

                        If selectedGroup Then
                            newWorkOrder.Groups.Add(groupItem)
                            Details.Add(String.Format("Selected assigned group: {0}", groupItem.Description))
                        End If

                        If reviewType <> RequirementReviewType.NotRequired AndAlso selectedReviewGroup Then
                            newWorkOrder.ReviewGroups.Add(groupItem)
                            Details.Add(String.Format("Selected review group: {0}", groupItem.Description))
                        End If
                    Next

                    If reqID > 0 Then
                        Dim basicReq As Requirement = Requirement.GetByPrimaryKey(formRequirementID)
                        newWorkOrder.BasedOnRequirementID = formRequirementID
                        For Each reqMeasure In basicReq.Measures
                            newWorkOrder.Measures.Add(WorkOrderMeasure.From(newWorkOrder, reqMeasure))
                        Next
                    Else
                        Dim formMaxId As Integer = Integer.Parse(collection("maxId"))
                        creationTrigger = NotificationTrigger.WorkOrder_AdhocCreate
                        ' Fething Measures
                        Details.Add("Manually created Measure list")
                        For i As Integer = 1 To formMaxId

                            Dim formMeasureName As String = collection(String.Format("measureName_{0}", i))

                            If Not String.IsNullOrEmpty(formMeasureName) Then

                                Dim measure As New WorkOrderMeasure()

                                Dim formMeasureOptimalLookupValue As String = collection(String.Format("measureOptimalLookupValue_{0}", i))
                                Dim formMeasureOptimalMin As String = collection(String.Format("measureOptimalMin_{0}", i))
                                Dim formMeasureOptimalMax As String = collection(String.Format("measureOptimalMax_{0}", i))
                                Dim formMeasureType As MeasureType = [Enum].Parse(GetType(MeasureType), collection(String.Format("measureType_{0}", i)))
                                Dim formMeasureLookupValue As String = collection(String.Format("measureLookupValue_{0}", i))
                                Dim formMeasureRequiredComments As String = collection(String.Format("measureRequiredComments_{0}", i))

                                measure.MeasureDescription = formMeasureName
                                measure.MeasureType = CInt(formMeasureType)
                                measure.LookupValue = formMeasureLookupValue
                                measure.OptimalLookupValue = formMeasureOptimalLookupValue

                                If formMeasureType = MeasureType.Integer Then
                                    measure.IntegerMin = Integer.Parse(formMeasureOptimalMin)
                                    measure.IntegerMax = Integer.Parse(formMeasureOptimalMax)
                                ElseIf formMeasureType = MeasureType.Decimal Then
                                    measure.DecimalMin = Decimal.Parse(formMeasureOptimalMin)
                                    measure.DecimalMax = Decimal.Parse(formMeasureOptimalMax)
                                End If

                                measure.RequiredComments = Integer.Parse(formMeasureRequiredComments)
                                Dim reqcom As String = "No"
                                If measure.RequiredComments > 0 Then
                                    reqcom = "Yes"
                                End If
                                newWorkOrder.Measures.Add(measure)
                                Details.Add(String.Format("Measure: {0}; Name: {1}; Type: {2};  Additional field: {3}", _
                                    i, measure.MeasureDescription, [Enum].Parse(GetType(MeasureType), measure.MeasureType), reqcom))
                            End If

                        Next
                        Details.Add("-----------------------------------------------------------")
                        ' End Fetching
                    End If
                    ' Add Comments 
                    Dim measureComments As New WorkOrderMeasure()
                    measureComments.MeasureDescription = "Comments"
                    measureComments.MeasureType = MeasureType.Text
                    newWorkOrder.Measures.Add(measureComments)

                    If Not ModelState.IsValid Then
                        'InitControls(req)
                        Return View()
                    End If

                    WorkOrder.Insert(newWorkOrder)

                    ModificationHistory.Insert(EntityType.WorkOrder, String.Format("Work Order #{0}", newWorkOrder.ID), _
                                           ModificationAction.Created, Application.CurrentUserInfo.UserID, Details, _
                                           newWorkOrder.ID, newWorkOrder.Asset.SiteDepartment.ParentID)
                    NotificationManager.CreateNotificationsByTrigger(creationTrigger, newWorkOrder.ID.ToString(), newWorkOrder)

                    Return RedirectToAction("Index")
                End If

                Return View()
            Catch
                Return View()
            End Try
        End Function
#End Region

#Region "Edit"

        <RequiresPageAcces(Page:=PageType.ManageWorkOrder)> _
        Function Edit(ByVal id As Integer) As ActionResult
            Dim currWorkOrder = WorkOrder.GetByPrimaryKey(id)
            InitWorkOrderControls(currWorkOrder)
            Return View()
        End Function


        <HttpPost()> _
        <RequiresPageAcces(Page:=PageType.ManageWorkOrder)> _
        Function Edit(ByVal id As Integer, ByVal collection As FormCollection) As ActionResult
            Dim currWorkOrder = WorkOrder.GetByPrimaryKey(id)
            Try
                Dim groups = GroupManager.GetAllByDepartmentFor(currWorkOrder.Asset.SiteDepartmentID, Application.CurrentUserInfo)
                Dim formRequirementType As RequirementType = [Enum].Parse(GetType(RequirementType), collection("RequirementType"))
                Dim reviewType As RequirementReviewType = [Enum].Parse(GetType(RequirementReviewType), collection("ReviewType"))
                Dim formDueTime As String = collection("txtDateDue")
                Dim formDesc As String = collection("txtDetails")
                Dim formReviewComments As String = collection("txtReviewComments")
                Dim changeDetails As New List(Of String)

                Dim dueDate As DateTime = DateTime.Now

                If Not DateTime.TryParse(formDueTime, dueDate) Then
                    ModelState.AddModelError("DateDue", "Wrong date/time format.")
                Else
                    If currWorkOrder.DateDue <> dueDate Then
                        changeDetails.Add("Changed Due Date")
                    End If
                    currWorkOrder.DateDue = dueDate
                End If

                If (currWorkOrder.RequirementType <> formRequirementType) Then
                    changeDetails.Add(String.Format("Changed Requirement Type to {0}", formRequirementType))
                End If
                currWorkOrder.RequirementType = formRequirementType
                If (currWorkOrder.Description <> formDesc) Then
                    changeDetails.Add("Changed Description")
                End If
                currWorkOrder.Description = formDesc
                If (currWorkOrder.ReviewType <> reviewType) Then
                    changeDetails.Add(String.Format("Changed Review Type to {0}", reviewType))
                End If
                currWorkOrder.ReviewType = reviewType
                For Each measure In currWorkOrder.Measures
                    Dim type As String = collection(String.Format("measureType_{0}", measure.ID))
                    Dim val As String = collection(String.Format("measure_{0}", measure.ID))
                    Dim comments As String = collection(String.Format("measureComment_{0}", measure.ID))
                    If Not String.IsNullOrEmpty(val) Then
                        If type = MeasureType.Checkbox Then
                            Dim lookup As String() = measure.LookupValue.Split(";")
                            If val.Split(",")(0) = "true" Then
                                val = lookup(0)
                            Else
                                val = lookup(1)
                            End If
                        End If
                        If (measure.CalibratedValue <> val) Then
                            changeDetails.Add(String.Format("Changed '{0}' measure value to: {1}", measure.MeasureDescription, val))
                        End If
                        measure.SetValue(val)
                        If (measure.MeasureComments <> comments) Then
                            changeDetails.Add(String.Format("Changed '{0}' measure comments", measure.MeasureDescription))
                        End If
                        measure.SetComments(comments)
                    End If
                Next

                If currWorkOrder.Status = WorkOrderStatusType.ReadyForReview Or currWorkOrder.Status = WorkOrderStatusType.ReadyForReviewWithExceptions Then
                    currWorkOrder.ReviewComments = formReviewComments
                End If

                currWorkOrder.Status = WorkOrderStatusType.AwaitingPost
                currWorkOrder.DateOpened = DateTime.Now.ToUniversalTime()

                For Each groupItem In groups
                    Dim stringSelectedGroup As String = collection(String.Format("cbxGroup_{0}", groupItem.ID))
                    Dim stringSelectedReviewGroup As String = collection(String.Format("cbxReviewGroup_{0}", groupItem.ID))
                    Dim selectedGroup As Boolean = False
                    Dim selectedReviewGroup As Boolean = False
                    If Not String.IsNullOrEmpty(stringSelectedGroup) Then
                        selectedGroup = Boolean.Parse(stringSelectedGroup.Split(",")(0))
                    End If

                    If Not String.IsNullOrEmpty(stringSelectedGroup) Then
                        selectedReviewGroup = Boolean.Parse(stringSelectedReviewGroup.Split(",")(0))
                    End If

                    For Each assignedgroup In currWorkOrder.Groups
                        If assignedgroup.ID = groupItem.ID Then
                            If Not selectedGroup Then
                                changeDetails.Add(String.Format("Remove assigned group {0}", groupItem.Description))
                            End If
                        End If
                    Next
                    For Each reviewdgroup In currWorkOrder.ReviewGroups
                        If reviewdgroup.ID = groupItem.ID Then
                            If Not selectedReviewGroup Then
                                changeDetails.Add(String.Format("Remove review group {0}", groupItem.Description))
                            End If
                        End If
                    Next

                    If selectedGroup Then
                        Dim bCheck As Boolean = True
                        For Each assignedgroup In currWorkOrder.Groups
                            If assignedgroup.ID = groupItem.ID Then
                                bCheck = False
                            End If
                        Next
                        If bCheck Then
                            changeDetails.Add(String.Format("Set assigned group {0}", groupItem.Description))
                        End If
                    End If
                    
                    If selectedReviewGroup Then
                        Dim bCheck As Boolean = True
                        For Each reviewdgroup In currWorkOrder.ReviewGroups
                            If reviewdgroup.ID = groupItem.ID Then
                                bCheck = False
                            End If
                        Next
                        If bCheck Then
                            changeDetails.Add(String.Format("Set review group {0}", groupItem.Description))
                        End If
                    End If
                Next

                currWorkOrder.Groups.Clear()
                currWorkOrder.ReviewGroups.Clear()

                For Each groupItem In groups
                    Dim stringSelectedGroup As String = collection(String.Format("cbxGroup_{0}", groupItem.ID))
                    Dim stringSelectedReviewGroup As String = collection(String.Format("cbxReviewGroup_{0}", groupItem.ID))
                    Dim selectedGroup As Boolean = False
                    Dim selectedReviewGroup As Boolean = False
                    If Not String.IsNullOrEmpty(stringSelectedGroup) Then
                        selectedGroup = Boolean.Parse(stringSelectedGroup.Split(",")(0))
                    End If

                    If Not String.IsNullOrEmpty(stringSelectedGroup) Then
                        selectedReviewGroup = Boolean.Parse(stringSelectedReviewGroup.Split(",")(0))
                    End If

                    If selectedGroup Then
                        currWorkOrder.Groups.Add(groupItem)
                    End If

                    If reviewType <> RequirementReviewType.NotRequired AndAlso selectedReviewGroup Then
                        currWorkOrder.ReviewGroups.Add(groupItem)
                    End If
                Next

                If Not ModelState.IsValid Then
                    InitWorkOrderControls(currWorkOrder)
                    Return View()
                End If

                If Not currWorkOrder.PerformedDate.HasValue Then
                    currWorkOrder.PerformedBy = Application.CurrentUserInfo.UserID
                    currWorkOrder.PerformedDate = DateTime.Now.ToUniversalTime()
                End If


                currWorkOrder.Save()
                ModificationHistory.Insert(EntityType.WorkOrder, String.Format("Work Order #{0}", currWorkOrder.ID), _
                                            ModificationAction.Modified, Application.CurrentUserInfo.UserID, changeDetails, _
                                            currWorkOrder.ID, currWorkOrder.Asset.SiteDepartment.ParentID)
                NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.WorkOrder_Calibrate, currWorkOrder.ID, currWorkOrder)
                NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.WorkOrder_StatusChange, currWorkOrder.ID, currWorkOrder)

                ViewData("Success_Mess") = SUCCESS_VALUE_SAVED_MESSAGE

            Catch

            End Try
            currWorkOrder = WorkOrder.GetByPrimaryKey(id)
            InitWorkOrderControls(currWorkOrder)
            ViewData("CurrWorkOrder") = currWorkOrder
            Return View()
        End Function

        Private Sub InitWorkOrderControls(ByRef currWorkOrder As WorkOrder)

            Dim groups = GroupManager.GetAllByDepartmentFor(currWorkOrder.Asset.SiteDepartmentID, Application.CurrentUserInfo)
            Dim departments = SiteDepartmentManager.GetAllDepartmentsBySiteFor(currWorkOrder.Asset.SiteDepartment.ParentID, Application.CurrentUserInfo)
            ViewData("DepartmentSource") = New SelectList(departments, "ID", "Description", currWorkOrder.Asset.SiteDepartment)
            ViewData("ReviewDepartmentSource") = New SelectList(departments, "ID", "Description", currWorkOrder.Asset.SiteDepartment)
            ViewData("CurrWorkOrder") = currWorkOrder
            ViewData("EntityType") = EntityType.WorkOrder
            ViewData("RequirementType") = New SelectList(RequirementTypeLookup.RetrieveAll(), "ID", "Description", currWorkOrder.RequirementType)
            ViewData("Groups") = groups
            ViewData("ReviewGroups") = groups
            ViewData("ReviewType") = New SelectList(RequirementReviewLookup.RetrieveAll(), "ID", "Description", currWorkOrder.ReviewType)

            For Each itemGroup In currWorkOrder.Groups
                ViewData(String.Format("SelectedGroup_{0}", itemGroup.ID)) = True
            Next

            For Each itemGroup In currWorkOrder.ReviewGroups
                ViewData(String.Format("SelectedReviewGroup_{0}", itemGroup.ID)) = True
            Next


        End Sub
#End Region

#Region "Delete"

        '
        ' GET: /WorkOrder/Delete/5
        <RequiresPageAcces(Page:=PageType.ManageWorkOrder)> _
        Function Delete(ByVal id As Integer) As ActionResult
            Return View()
        End Function

        '
        ' POST: /WorkOrder/Delete/5

        <HttpPost()> _
        Function Delete(ByVal id As Integer, ByVal collection As FormCollection) As ActionResult
            Try
                ' TODO: Add delete logic here

                Return RedirectToAction("Index")
            Catch
                Return View()
            End Try
        End Function
#End Region

#Region "AJAX"
        <HttpPost()> _
        Function GetDepartmentDDBySiteID(ByVal siteID As Integer?) As ActionResult
            If Not siteID.HasValue Then
                siteID = 0
            End If
            ViewData("Department") = New SelectList(SiteDepartmentManager.GetDepartamentsWithAssetForSite(siteID), "ID", "Description")
            Return PartialView("~/Views/WorkOrder/Controls/AllDepartmentDropDown.ascx")
        End Function

        Function GetGroupDDBySiteID(ByVal siteID As Integer?) As ActionResult
            If Not siteID.HasValue Then
                siteID = 0
            End If
            ViewData("Group") = New SelectList(GroupManager.GetAllBySiteFor(siteID, Application.CurrentUserInfo), "ID", "Description")
            Return PartialView("~/Views/WorkOrder/Controls/AllGroupDropDown.ascx")
        End Function

        Function SearchAssetByBarCode(ByVal q As String) As ActionResult
            Dim assets As IEnumerable(Of Asset) = AssetManager.SearchAssetByBarCodeFor(Application.CurrentUserInfo, q)
            Dim result = AssetWrapper.ConvertToWrapperList(assets)
            Return Json(result.ToArray(), JsonRequestBehavior.AllowGet)
        End Function

        Function SearchAssetByName(ByVal q As String) As ActionResult
            Dim assets As IEnumerable(Of Asset) = AssetManager.SearchAssetByNameFor(Application.CurrentUserInfo, q)
            Dim result = AssetWrapper.ConvertToWrapperList(assets)

            Return Json(result.ToArray(), JsonRequestBehavior.AllowGet)
        End Function

        Function SearchAssetByNameAndID(ByVal q As String) As ActionResult
            Dim wrapperResult As List(Of AssetWrapper)
            If Not IsNumeric(q) Then
                Dim assets As IEnumerable(Of Asset) = AssetManager.SearchAssetByNameFor(Application.CurrentUserInfo, q)
                wrapperResult = AssetWrapper.ConvertToWrapperList(assets)
            Else
                wrapperResult = New List(Of AssetWrapper)
                Dim a As Asset = Asset.GetByPrimaryKey(Integer.Parse(q))
                If a IsNot Nothing AndAlso (Application.CurrentUserInfo.IsSuperUser Or (a.SiteDepartment IsNot Nothing AndAlso a.SiteDepartment.ParentID = Application.CurrentUserInfo.SiteID)) Then
                    wrapperResult.Add(AssetWrapper.GetFrom(a))
                End If
            End If

            Return Json(wrapperResult.ToArray(), JsonRequestBehavior.AllowGet)
        End Function


        <HttpPost()> _
        Function GetLatestWorkOrderLinkByAssetBarCode(ByVal barcode As String) As ActionResult
            Dim result As New JSONActionResult()
            result.Result = "Asset/NotFound"
            Dim asset As Asset = asset.GetByBarCode(barcode)
            Dim wo As WorkOrder

            If asset IsNot Nothing Then
                If Application.CurrentUserInfo.IsSuperUser Then
                    wo = WorkOrder.GetLatestByAsset(asset.AssetID)
                Else
                    wo = WorkOrder.GetLatestByAssetFor(Application.CurrentUserInfo.GroupIDs, asset.AssetID)
                End If
                If wo Is Nothing Then
                    result.Result = String.Format("Asset/Edit/{0}", asset.AssetID)
                Else
                    result.Result = String.Format("WorkOrder/Process/{0}", wo.ID)
                End If
            Else
                result.Result = String.Format("Asset/NotFound/{0}", barcode)
            End If

            Return Json(result)
        End Function

        <HttpPost()> _
        Function GetLatestWorkOrderLinkByAssetName(ByVal name As String) As ActionResult
            Dim result As New JSONActionResult()
            result.Result = "Asset/NotFound"
            Dim asset As Asset = asset.GetByName(name)
            Dim wo As WorkOrder

            If asset IsNot Nothing Then
                If Application.CurrentUserInfo.IsSuperUser Then
                    wo = WorkOrder.GetLatestByAsset(asset.AssetID)
                Else
                    wo = WorkOrder.GetLatestByAssetFor(Application.CurrentUserInfo.GroupIDs, asset.AssetID)
                End If
                If wo Is Nothing Then
                    result.Result = String.Format("Asset/Edit/{0}", asset.AssetID)
                Else
                    result.Result = String.Format("WorkOrder/Process/{0}", wo.ID)
                End If
            Else
                result.Result = String.Format("Asset/NotFound/{0}?name=y", name)
            End If

            Return Json(result)
        End Function

        <HttpPost()> _
        Function GetLatestWorkOrderByAssetID(ByVal id As Integer) As ActionResult
            Dim wo As WorkOrder
            If Application.CurrentUserInfo.IsSuperUser Then
                wo = WorkOrder.GetLatestByAsset(id)
            Else
                wo = WorkOrder.GetLatestByAssetFor(Application.CurrentUserInfo.GroupIDs, id)
            End If

            If wo Is Nothing Then
                wo = New WorkOrder With {.ID = 0, .Asset = New Asset}
            End If

            Return Json(WorkOrderWrapper.GetFrom(wo))
        End Function

        <HttpPost()> _
        Function WorkOrderContent(ByVal reqID As Integer, ByVal assetID As Integer) As ActionResult
            Dim forAsset = Asset.GetByPrimaryKey(assetID)
            Dim currReq As Requirement
            If reqID > 0 Then
                currReq = Requirement.GetByPrimaryKey(reqID)
            Else
                currReq = New Requirement()
                ViewData("MeasureList") = New List(Of WorkOrderMeasure)
            End If

            Dim departments = SiteDepartmentManager.GetAllDepartmentsBySiteFor(forAsset.SiteDepartment.ParentID, Application.CurrentUserInfo)
            Dim groups As IEnumerable(Of Group) = New List(Of Group)
            If departments.Count > 0 Then
                groups = GroupManager.GetAllByDepartmentFor(forAsset.SiteDepartmentID, Application.CurrentUserInfo)
            End If

            ViewData("Groups") = groups
            ViewData("ReviewGroups") = groups
            ViewData("DepartmentSource") = New SelectList(departments, "ID", "Description")
            ViewData("ReviewDepartmentSource") = New SelectList(departments, "ID", "Description")
            ViewData("RequirementType") = New SelectList(RequirementTypeLookup.RetrieveAll(), "ID", "Description")
            ViewData("ReviewType") = New SelectList(RequirementReviewLookup.RetrieveAll(), "ID", "Description", RequirementReviewType.NotRequired)
            ViewData("NextWorkOrderID") = WorkOrder.GetNextID()

            Return PartialView("~/Views/WorkOrder/Controls/WorkOrderContent.ascx")
        End Function

        <HttpPost()> _
        Function GetGroupsByDepartmentID(ByVal depID As Integer?) As ActionResult
            If Not depID.HasValue Then
                depID = 0
            End If
            ViewData("Groups") = GroupManager.GetAllByDepartmentFor(depID, Application.CurrentUserInfo)
            Return PartialView("~/Views/WorkOrder/Controls/GroupGrid.ascx")
        End Function

        <HttpPost()> _
        Function GetReviewGroupsByDepartmentID(ByVal depID As Integer?) As ActionResult
            If Not depID.HasValue Then
                depID = 0
            End If
            ViewData("ReviewGroups") = GroupManager.GetAllByDepartmentFor(depID, Application.CurrentUserInfo)
            Return PartialView("~/Views/WorkOrder/Controls/GroupGrid.ascx", "Review")
        End Function

        <HttpPost()> _
        Function GetAssetTypesByDepartment(ByVal id As Integer) As ActionResult
            Dim assets As List(Of Asset)

            assets = Asset.RetrieveAll(0, 0, id).ToList()

            Dim types As List(Of AssetType) = assets.Select(Function(a) a.AssetType).Distinct().ToList()

            ViewData("FilterAssetType") = New SelectList(types, "ID", "Description")
            Return PartialView("~/Views/WorkOrder/Controls/AssetTypeList.ascx")
        End Function

        <HttpPost()> _
        Function GetAssetsByDepartmentAndType(ByVal id As Integer, ByVal typeID As Integer) As ActionResult
            ViewData("FilterAssetName") = New SelectList(Asset.RetrieveAllByDepartmentIDAndTypeID(id, typeID), "AssetID", "AssetName")
            Return PartialView("~/Views/WorkOrder/Controls/AssetNameList.ascx")
        End Function

        <HttpPost()> _
        Function GetAssetByID(ByVal id As Integer) As ActionResult
            Dim asset As Asset = asset.GetByPrimaryKey(id)
            Return Json(AssetWrapper.GetFrom(asset))
        End Function

        <HttpPost()> _
        Function RequirementList(ByVal assetTypeID As Integer) As ActionResult
            ViewData("RequirementList") = Requirement.RetrieveAllByAssetType(assetTypeID)
            Return PartialView("~/Views/WorkOrder/Controls/RequirementList.ascx")
        End Function

        <HttpPost()> _
        Function CheckAuthentication(ByVal psw As String) As ActionResult
            Dim bCheck As Boolean = False
            Dim currUser As DataAccess.User = DataAccess.User.GetByPrimaryKey(Application.CurrentUserInfo.UserID)
            If (currUser.Password = psw) Then
                bCheck = True
            End If
            Return Json(bCheck)
        End Function


#Region "AJAX Filters"
        <HttpPost()> _
        Function FilterWorkOrder(ByVal assetTypeID As Integer?, ByVal locationID As Integer?, ByVal groupID As Integer?, _
                                  ByVal strDateFrom As String, ByVal strDateTo As String, ByVal status As String) As ActionResult

            Dim dateFrom As DateTime = DateTime.UtcNow.Date.AddYears(-5)
            Dim dateTo As DateTime = DateTime.UtcNow.Date

            If Not String.IsNullOrEmpty(strDateFrom) Then
                DateTime.TryParse(strDateFrom, dateFrom)
            End If

            If Not String.IsNullOrEmpty(strDateTo) Then
                DateTime.TryParse(strDateTo, dateTo)
            End If

            dateTo = dateTo.AddDays(1).AddSeconds(-1)

            If Not assetTypeID.HasValue Then
                assetTypeID = 0
            End If
            If Not locationID.HasValue Then
                locationID = 0
            End If

            If Not groupID.HasValue Then
                groupID = 0
            End If

            Dim workOrders As IEnumerable(Of WorkOrder)
            Dim workOrderStatus As WorkOrderStatusType
            Dim userInfo = Application.CurrentUserInfo

            If Not String.IsNullOrEmpty(status) AndAlso [Enum].TryParse(status, workOrderStatus) Then
                workOrders = WorkOrderManager.GetFilteredByStatusFor(userInfo, assetTypeID, locationID, groupID, _
                                                                     TimeZoneManager.ConvertToCentralTimeFor(dateFrom), TimeZoneManager.ConvertToCentralTimeFor(dateTo), workOrderStatus)
            Else
                workOrders = WorkOrderManager.GetFilteredFor(userInfo, assetTypeID, locationID, groupID, _
                                                             TimeZoneManager.ConvertToCentralTimeFor(dateFrom), TimeZoneManager.ConvertToCentralTimeFor(dateTo))
            End If

            ViewData("WorkOrderList") = workOrders

            Return PartialView("~/Views/WorkOrder/Controls/WorkOrderGrid.ascx")
        End Function

        <HttpPost()> _
        Function FilterPostingWorkOrder(ByVal assetTypeID As Integer?, ByVal locationID As Integer?, _
                                            ByVal strDateFrom As String, ByVal strDateTo As String) As ActionResult

            Dim dateFrom As DateTime = DateTime.UtcNow.Date.AddYears(-5)
            Dim dateTo As DateTime = DateTime.UtcNow.Date

            If Not String.IsNullOrEmpty(strDateFrom) Then
                DateTime.TryParse(strDateFrom, dateFrom)
            End If

            If Not String.IsNullOrEmpty(strDateTo) Then
                DateTime.TryParse(strDateTo, dateTo)
            End If

            dateTo = dateTo.AddDays(1).AddSeconds(-1)

            If Not assetTypeID.HasValue Then
                assetTypeID = 0
            End If
            If Not locationID.HasValue Then
                locationID = 0
            End If

            Dim workOrderList As IEnumerable(Of WorkOrder) = WorkOrderManager.GetFilteredByStatusFor(Application.CurrentUserInfo, assetTypeID, _
                                                                                                     locationID, 0, _
                                                                                                     TimeZoneManager.ConvertToCentralTimeFor(dateFrom), TimeZoneManager.ConvertToCentralTimeFor(dateTo), _
                                                                                                     WorkOrderStatusType.AwaitingPost)


            ViewData("WorkOrderList") = workOrderList

            Return PartialView("~/Views/WorkOrder/Controls/PostingWorkOrderGrid.ascx")
        End Function

        <HttpPost()> _
        Function FilterReviewWorkOrder(ByVal assetTypeID As Integer?, ByVal locationID As Integer?, ByVal groupID As Integer?, _
                                 ByVal strDateFrom As String, ByVal strDateTo As String, ByVal status As String) As ActionResult

            Dim dateFrom As DateTime = DateTime.UtcNow.Date.AddYears(-5)
            Dim dateTo As DateTime = DateTime.UtcNow.Date

            If Not String.IsNullOrEmpty(strDateFrom) Then
                DateTime.TryParse(strDateFrom, dateFrom)
            End If

            If Not String.IsNullOrEmpty(strDateTo) Then
                DateTime.TryParse(strDateTo, dateTo)
            End If

            dateTo = dateTo.AddDays(1).AddSeconds(-1)

            If Not assetTypeID.HasValue Then
                assetTypeID = 0
            End If
            If Not locationID.HasValue Then
                locationID = 0
            End If
            If Not groupID.HasValue Then
                groupID = 0
            End If

            Dim workOrders As IEnumerable(Of WorkOrder)
            Dim workOrderStatus As WorkOrderStatusType


            Dim userInfo = Application.CurrentUserInfo

            If Not String.IsNullOrEmpty(status) AndAlso [Enum].TryParse(status, workOrderStatus) Then
                workOrders = WorkOrderManager.GetFilteredForReview(Application.CurrentUserInfo, locationID, groupID, _
                                                                   0, TimeZoneManager.ConvertToCentralTimeFor(dateFrom), TimeZoneManager.ConvertToCentralTimeFor(dateTo), _
                                                                   workOrderStatus)
            Else
                workOrders = WorkOrderManager.GetFilteredForReview(Application.CurrentUserInfo, locationID, 0, groupID, _
                                                                   TimeZoneManager.ConvertToCentralTimeFor(dateFrom), TimeZoneManager.ConvertToCentralTimeFor(dateTo))
            End If

            ViewData("WorkOrderList") = workOrders

            Return PartialView("~/Views/WorkOrder/Controls/ReviewWorkOrderGrid.ascx")
        End Function


        <HttpPost()> _
        Function FilterAsset(ByVal assetTypeID As Integer?, ByVal groupID As Integer?) As ActionResult

            If Not assetTypeID.HasValue Then
                assetTypeID = 0
            End If
            If Not groupID.HasValue Then
                groupID = 0
            End If

            Dim userInfo = Application.CurrentUserInfo
            Dim assets As IEnumerable(Of Asset) = AssetManager.GetFilteredFor(Application.CurrentUserInfo, assetTypeID, groupID)

            ViewData("Assets") = assets

            Return PartialView("~/Views/WorkOrder/Controls/AssetGrid.ascx")
        End Function

#End Region

#End Region

    End Class
End Namespace